/* $Id:unit.h $ */
/*
   Copyright (C) 2007 by Jurjen Stellingwerff <jurjen@stwerff.xs4all.nl>
   Part of the Moros Project http://moros.sourceforge.net/

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 3.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.

   See the COPYING file for more details.
*/

#ifndef __UNIT_H
#define __UNIT_H

#include <string>
#include <map>
#include <list>
using namespace std;

#include "action_level.h"
#include "material.h"
#include "background_level.h"
#include "culture_part.h"
#include "skill_level.h"
#include "stat_amount.h"

#define loopUnitSpecials(r,v) loopMapi((r)->listSpecials(),v,class action_level)
#define loopUnitWeapons(r,v) loopSingle((r)->listWeapons(),v,class material,list)
#define loopUnitBackground(r,v) loopSingle((r)->listBackground(),v,class background_level,list)
#define loopUnitCulture(r,v) loopMap((r)->listCulture(),v,class culture_part)
#define loopUnitSkills(r,v) loopMap((r)->listSkills(),v,class skill_level)
#define loopUnitStats(r,v) loopMap((r)->listStats(),v,class stat_amount)

class unit {
    string name;
    string description;
    int size;
    map<int,class action_level> specials;
    int maxSpecials;
    map<string,class material> weapons;
    map<string,class background_level> background;
    map<string,class culture_part> culture;
    map<string,class skill_level> skills;
    map<string,class stat_amount> stats;
public:
    unit();

    // Field : name
    const string getName() const;
    void setName(const string v);

    // Field : description
    const string getDescription() const;
    void setDescription(const string v);

    // Field : size
    const int getSize() const;
    void setSize(const int v);

    // Field : specials
    class action_level& getSpecials(const int v);
    map<int,class action_level>& listSpecials();
    void setSpecials(class action_level &v);
    void delSpecials(const int v);
    const bool isSpecials(const int v) const;

    // Field : weapons
    class material& getWeapons(const string v);
    list<class material>& listWeapons();
    void setWeapons(class material &v);
    void delWeapons(const string v);
    const bool isWeapons(const string v) const;

    // Field : background
    class background_level& getBackground(const string v);
    list<class background_level>& listBackground();
    void setBackground(class background_level &v);
    void delBackground(const string v);
    const bool isBackground(const string v) const;

    // Field : culture
    class culture_part& getCulture(const string v);
    map<string,class culture_part>& listCulture();
    void setCulture(class culture_part &v);
    void delCulture(const string v);
    const bool isCulture(const string v) const;

    // Field : skills
    class skill_level& getSkills(const string v);
    map<string,class skill_level>& listSkills();
    void setSkills(class skill_level &v);
    void delSkills(const string v);
    const bool isSkills(const string v) const;

    // Field : stats
    class stat_amount& getStats(const string v);
    map<string,class stat_amount>& listStats();
    void setStats(class stat_amount &v);
    void delStats(const string v);
    const bool isStats(const string v) const;

    void save(class channel &ch);
    void load(class channel &ch);
    void xml(ofstream &f, int l=0, int r=0);
};

// Repository

#define loopUnits(v) loopMap(unit_repo.listUnit(),v,class unit)

class unitRepository {
    map<string,unit> units;
public:
    class unit& getUnit(const string v);
    void setUnit(class unit& v);
    map<string,class unit>& listUnit();
    void delUnit(const string v);
    const bool isUnit(const string v) const;
    multimap<string, sigc::signal<void, class unit& > > relations;
    bool load(class channel &ch);
    void save(class channel &ch);
};

extern unitRepository unit_repo;

#endif // __UNIT_H
